home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / mouse.swg < prev    next >
Text File  |  1994-09-22  |  53KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00004                                                                           1      08-24-9413:46ALL                      ANDREW EIGUS             Good Mouse Support       SWAG9408    bFƒ⌡    45     l╚   πUnit Mouse;π{ Copyright (c) 1991, Crazy Systems Software, Inc. }ππ{$G+}ππ{π *************************************************π *                                               *π *       Mouse in Text Mode Interface Unit       *π *            for Borland Pascal 7.0             *π *                                               *π *      Completely written by  Andrew Eigus      *π *************************************************π}ππinterfaceππtypeπ  TMouseWinRect = recordπ    X1, Y1, X2, Y2 : wordπ  end;ππ  TMouseParamTable = recordπ    BaudRate,  { Baud rate / 100 }π    Emulation,π    ReportRate, { Report rate }π    FirmRev,π    ZeroWord,  { Should be zero }π    Port,  { Com Port used }π    PhysButtons, { Physical buttons }π    LogButtons : word { Logical buttons }π  end;ππ  TMouseRec = recordπ    Keys,π    Hzints,π    Page,π    XCoord,π    YCoord,π    HSpeed,π    VSpeed,π    DSpeed : word;π    Column,π    Row : byte;π    W : TMouseWinRect;π    ButtonClicked : byte;π    ParamTable : TMouseParamTableπ  end;ππconstπ  LeftButton  = 1;π  MidButton   = 4;π  RightButton = 2;ππ  mNoInts    = 0;π  m30HzInts  = 1;π  m50HzInts  = 2;π  m100HzInts = 3;π  m200HzInts = 4;ππvarπ  M : TMouseRec;π  MouseInstalled : boolean;ππfunction InstallMouse : boolean;πfunction GetMouseInfo(var M : TMouseRec) : byte;πfunction ButtonReleased : boolean;πprocedure SetMouseCursor(CursorOn : boolean);πprocedure SetMouseCursorType(HotSpotX, HotSpotY : word; var CursorImage);πprocedure MoveMouseTo(XCoord, YCoord : integer);πprocedure SetMouseWindow(X1, Y1, X2, Y2 : word);πprocedure GetMouseSpeed;πprocedure SetMouseSpeed(HorSpeed, VrtSpeed, DblSpeed : integer);πprocedure SetMouseInts(Hz : word);πfunction GetMousePage : word;πprocedure SetMousePage(Page : word);πprocedure UninstallMouse;ππimplementationππFunction InstallMouse; assembler;πAsmπ  XOR AX,AX  { zero function }π  INT 33hπ  CMP AL,0π  JE  @@1π  MOV MouseInstalled,Trueπ  LEA DI,Mπ  MOV [ES:DI](TMouseRec).Keys,0π  MOV [ES:DI](TMouseRec).Keys,BXπ  PUSH ESπ  PUSH DIπ  CALL GetMouseInfoπ  CALL GetMousePageπ  CALL GetMouseSpeedπ  MOV [ES:DI](TMouseRec).W.X1,1π  MOV [ES:DI](TMouseRec).W.Y1,1π  MOV [ES:DI](TMouseRec).W.X2,639π  MOV [ES:DI](TMouseRec).W.Y2,199π  MOV AX,246Chπ  LEA DX,M.ParamTableπ  INT 33hπ  MOV AL,Trueπ@@1:πEnd; { InstallMouse }ππFunction GetMouseInfo; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,0003hπ  INT 33hπ  LES DI,Mπ  MOV [ES:DI](TMouseRec).XCoord,CXπ  SHR CX,3π  INC CLπ  MOV [ES:DI](TMouseRec).Column,CLπ  MOV [ES:DI](TMouseRec).YCoord,DXπ  SHR DX,3π  INC DLπ  MOV [ES:DI](TMouseRec).Row,DLπ  MOV [ES:DI](TMouseRec).ButtonClicked,BLπ  MOV AL,BL   { LeftButton, MidButton or RightButton }π@@1:πEnd; { GetMouseInfo }ππFunction ButtonReleased; assembler;πAsmπ  LEA DI,Mπ  PUSH ESπ  PUSH DIπ  CALL GetMouseInfoπ  MOV AL,Trueπ  CMP BL,0π  JE  @@1π  MOV AL,Falseπ@@1:πEnd; { ButtonReleased }ππProcedure SetMouseCursor; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@2π  MOV AX,0001hπ  CMP CursorOn,Trueπ  JE  @@1π  MOV AX,0002hπ@@1:π  INT 33hπ@@2:πEnd; { SetMouseCursor }ππProcedure SetMouseCursorType; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,000Ahπ  MOV BX,HotSpotXπ  MOV CX,HotSpotYπ  LES DX,CursorImageπ  INT 33hπ@@1:πEnd; { SetMouseCursorType }ππProcedure MoveMouseTo; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,0004hπ  MOV CX,XCoordπ  MOV DX,YCoordπ  INT 33hπ@@1:πEnd; { MoveMouseTo }ππProcedure SetMouseWindow; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  LEA DI,Mπ  MOV AX,0007hπ  MOV CX,X1π  MOV [ES:DI](TMouseRec).W.X1,CXπ  MOV DX,X2π  MOV [ES:DI](TMouseRec).W.X2,DXπ  INT 33hπ  MOV AX,0008hπ  MOV CX,Y1π  MOV [ES:DI](TMouseRec).W.Y1,CXπ  MOV DX,Y2π  MOV [ES:DI](TMouseRec).W.Y2,DXπ  INT 33hπ@@1:πEnd; { SetMouseWindow }ππProcedure GetMouseSpeed; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,001Bhπ  INT 33hπ  LEA DI,Mπ  MOV [ES:DI](TMouseRec).HSpeed,BXπ  MOV [ES:DI](TMouseRec).VSpeed,CXπ  MOV [ES:DI](TMouseRec).DSpeed,DXπ@@1:πEnd; { GetMouseSpeed }ππProcedure SetMouseSpeed; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,001Ahπ  MOV BX,HorSpeedπ  MOV CX,VrtSpeedπ  MOV DX,DblSpeedπ  INT 33hπ  CALL GetMouseSpeedπ@@1:πEnd; { SetMouseSpeed }ππProcedure SetMouseInts; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,001Chπ  MOV BX,Hzπ  INT 33hπ@@1:πEnd; { SetMouseInts }ππFunction GetMousePage; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,001Ehπ  INT 33hπ  LEA DI,Mπ  MOV [ES:DI](TMouseRec).Page,BXπ  MOV AX,BXπ@@1:πEnd; { GetMousePage }ππProcedure SetMousePage; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,001Dπ  MOV BX,Pageπ  INT 33hπ  CALL GetMousePageπ@@1:πEnd; { SetMousePage }ππProcedure UninstallMouse; assembler;πAsmπ  CMP MouseInstalled,Trueπ  JNE @@1π  MOV AX,0020hπ  INT 33hπ@@1:πEnd; { UninstallMouse }ππBeginπ  MouseInstalled := False;π  FillChar(M, SizeOf(TMouseRec), 0)πEnd. { Mouse }ππ{---now the demo program---}ππProgram MouDemo;ππuses Crt, Mouse;ππBeginπ  if InstallMouse thenπ  beginπ    ClrScr;π    SetMouseCursor(True);π    WriteLn('Mouse is installed.');π    WriteLn('Click left mouse button in the upper left corner of your ' +π      'screen to quit.');π    repeatπ      GetMouseInfo(M);π    until (M.ButtonClicked = LeftButton) and (M.Column = 1) and (M.Row = 1);π    Write('Waiting to release left button...');π    repeat until ButtonReleased;π    Write(#13);π    ClrEol;π    SetMouseCursor(False);π    UninstallMouseπ  end else WriteLn('Mouse is NOT installed.')πEnd.ππ                                                                                                                  2      08-24-9413:46ALL                      FRED JOHNSON             Good Mouse Support       SWAG9408    Σ╛└    80     l╚   πunit mouse3;π{-------------------------------------------------------------------------πReference Tableπ  M1 M2 M3 M4π  1  0  0  0   = Turn Mouse on with cursor.π  2  0  0  0   = Turn Mouse Off.π  3  ?  ?  ?   = To see if buttons are pressed.π                  Test registers with logical AND   (M2 is BX register)π                  M2 and 1 = Left Buttonπ                  M2 and 2 = Right Buttonπ                  M2 and 3 = Left and Right Buttonsπ                  M2 and 4 = Middle Buttonπ                  M2 and 5 = Left and Middle Buttonsπ                  M2 and 6 = Right and Middle Buttonsπ                  M2 and 7 = Left, Middle and Right Buttonsππ  3  0  X  Y  = Get Mouse Cursor position.π                 M3 (CX) will return Mouse X coordinates. ( 0   = left wall)π                 M4 (DX) will return Mouse Y coordinates. ( 632 = right wall)π                 Divide by 8 and add 1 for Turbo Pascal XY position.ππ  4  0  X  Y  = Set Mouse Cursor position.π                 M3 (CX) set for Mouse X coordinate.      ( 0   = left wall)π                 M4 (DX) set for Mouse Y coordinate.      ( 632 = right wall)ππ  6  ?  0  0  = Mouse Button Release Status.              M2 (BX) set if Trueπ}ππinterfaceππUSES dos,crt;ππTYPEπ   xMouseFuncs = recordπ      bFunction : function : boolean;π   end;ππVARπ   M1,M2,M3,M4 : word;π   Regs        : Registers;  { MS DOS Registers }ππPROCEDURE Mouse( var M1,M2,M3,M4 : word );πPROCEDURE DeInitMouse;πPROCEDURE InitMouse;πPROCEDURE GetMousePos;πPROCEDURE GetMouseStats;πPROCEDURE SetMousePos(xM3, yM4:word);ππFUNCTION  MPos(wPosition : word) : word;πFUNCTION  LeftButton             : Boolean;πFUNCTION  LeftAndRightButtons    : Boolean;πFUNCTION  LeftAndMiddleButtons   : Boolean;πFUNCTION  RightAndMiddleButtons  : Boolean;πFUNCTION  LeftMidAndRightButtons : Boolean;πFUNCTION  MiddleButton           : Boolean;πFUNCTION  RightButton            : Boolean;πFUNCTION  MouseRelease           : boolean;ππconstπ   MouseButton : array[1..7] of xMouseFuncs =π      (π      (bFunction : LeftButton),π      (bFunction : RightButton),π      (bFunction : LeftAndRightButtons),π      (bFunction : MiddleButton),π      (bFunction : LeftAndMiddleButtons),π      (bFunction : RightAndMiddleButtons),π      (bFunction : LeftMidAndRightButtons)π      );ππ   MOUSE_REST  = 0;π   MOUSE_L     = 1;π   MOUSE_R     = 2;π   MOUSE_L_R   = 3;π   MOUSE_M     = 4;π   MOUSE_L_M   = 5;π   MOUSE_R_M   = 6;π   MOUSE_L_M_R = 7;ππimplementationπππFUNCTION MPos(wPosition : word) : word;π   beginπ      MPos := (wPosition div 8)+1;π   end;ππFUNCTION LeftButton : Boolean;π   beginπ      LeftButton := FALSE;π      if (M2 and 1) <> MOUSE_REST thenπ         begin                { if left button pressed }π            LeftButton := TRUE;π         end;π   end;ππFUNCTION RightButton : Boolean;π   beginπ      RightButton := FALSE;π      if (M2 and 2) <> MOUSE_REST thenπ         begin                { if right button pressed }π            RightButton := TRUE;π         end;π   end;ππFUNCTION LeftAndRightButtons : Boolean;π   beginπ      LeftAndRightButtons := FALSE;π      if (M2 and 3) = 3 thenπ         beginπ            LeftAndRightButtons := TRUE;π         end;π   end;ππFUNCTION MiddleButton : Boolean;π   beginπ      MiddleButton := FALSE;π      if (M2 and 4) <> MOUSE_REST thenπ         beginπ            MiddleButton := TRUE;π         end;π   end;ππFUNCTION LeftAndMiddleButtons : Boolean;π   beginπ      LeftAndMiddleButtons := FALSE;π      if (M2 and 5) = MOUSE_L_M thenπ         beginπ            LeftAndMiddleButtons := TRUE;π         end;π   end;ππFUNCTION RightAndMiddleButtons : Boolean;π   beginπ      RightAndMiddleButtons := FALSE;π      if (M2 and 6) = MOUSE_R_M thenπ         beginπ            RightAndMiddleButtons := TRUE;π         end;π   end;ππFUNCTION LeftMidAndRightButtons : Boolean;π   beginπ      LeftMidandRightButtons := FALSE;π      if (M2 and 7) = MOUSE_L_M_R thenπ         beginπ            LeftMidAndRightButtons := TRUE;π         end;π   end;ππFUNCTION MouseRelease : boolean;π  beginπ     MouseRelease := FALSE;π     M1 := 6;π     Mouse( M1,M2,M3,M4 ); { Set mouse cursor ON }π     if MOUSE_REST <> M2 thenπ        beginπ           MouseRelease := TRUE;π        end;π  end;ππPROCEDURE Mouse( var M1,M2,M3,M4 : word );π   beginπ      With Regs DOπ         beginπ            AX := M1;π            BX := M2;π            CX := M3;π            DX := M4;π         end;π      intr($33,Regs); { Interrupt $33, the mouse interrupt }ππ      With Regs DOπ         beginπ            M1 := AX;π            M2 := BX;π            M3 := CX;π            M4 := DX;π         end;π  end;ππPROCEDURE InitMouse;π  beginπ     M1 := 1;π     Mouse( M1,M2,M3,M4 ); { Set mouse cursor ON }π  end;ππPROCEDURE DeInitMouse;π  beginπ     M1 := 2;π     Mouse( M1,M2,M3,M4 ); { Set mouse cursor OFF }π  end;ππPROCEDURE GetMousePos;π   beginπ      M1 := 3;π      Mouse(M1, M2, M3, M4);π   end;πππPROCEDURE GetMouseStats;π   beginπ      M1 := 3;π      M2 := 0;π      M3 := 0;π      m4 := 0;π      Mouse(M1, M2, M3, M4);π   end;ππPROCEDURE SetMousePos(xM3, yM4:word);π   beginπ      M1 := 4;π      Mouse(M1, M2, xM3, yM4);π   end;ππbeginπ   initmouse; {Take this out if you do not wish mouse to auto initialize}πend.ππ{-----------------------------   DEMO PROGRAM ---------------------}ππUSES dos, crt, mouse3, Frame2;ππVARπ   satisfied  : boolean;    { if mouse pos and button are together }ππCONSTπ   Menu_ClrScr = 'C';π   Menu_Quit   = 'Q';ππPROCEDURE DO_Mssg;π   beginπ      gotoxy(1,24);π      writeln('Push Middle Button or L/R buttons together for menu');π      write('XY Coordinates totalling 40 will produce beep');π   end;ππFUNCTION MenuHit(cChar : char) : Boolean;π   beginπ      GetMousePos;π      MenuHit := FALSE;π      if (27 = MPos(M3)) and (MouseButton[MOUSE_L].bFunction) thenπ         beginπ            if (Menu_ClrScr = cChar) and (11 = MPos(M4)) thenπ               beginπ                  MenuHit := TRUE;π                  ClrScr;π                  Do_Mssg;π                  exit;π               end;ππ            if (Menu_Quit = cChar) and (12 = MPos(M4)) thenπ               beginπ                  MenuHit := TRUE;π                  exit;π               end;π         end;π   end;ππBEGINπ   satisfied := false;π   textcolor(7); { Grey }π   ClrScr;π   Do_Mssg;ππ   while not keypressed do { until  KEYBOARD key is pressed }π      beginπ         GetMouseStats;π         gotoxy(1,1);π         write('M3 =',MPos(M3):2,π            ' M4 =',MPos(M4):2);ππ         if (MPos(M3)+MPos(M4) = 40) thenπ            beginπ               write(#7);π            end;ππ         if MouseButton[MOUSE_L].bFunction  thenπ            beginπ               gotoxy(16,1);π               write('Left Button');π               clreol;π            end;ππ         if MouseButton[MOUSE_R].bFunction thenπ            beginπ               gotoxy(16,1);π               write('Right Button');π               clreol;π            end;ππ         if (MouseButton[MOUSE_M].bFunction= TRUE) or      {Middle Button}π            (MouseButton[MOUSE_L_R].bFunction = TRUE) then  {Left & Right}π               beginπ                  SetMousePos(30*8, 11*8);  { Sets MCursor out of way }π                  Frame(1,25,10,39,13);π                  gotoxy(26,11);π                  textcolor(14);π                  write(' ',Menu_ClrScr);π                  textcolor(07);π                  write('learscreen');π                  gotoxy(26,12);π                  textcolor(14);π                  write(' ',Menu_Quit);π                  textcolor(07);π                  write('uit');π                  repeatπ                     if MenuHit(Menu_ClrScr) = TRUE thenπ                        beginπ                           satisfied := true;π                           SetMousePos(0,0); {Sets MCursor out of way }π                        end;π                     gotoxy(1,1);π                     write('M3 =',MPos(M3):2,π                        ' M4 =',MPos(M4):2);π                     clreol;ππ                     if MenuHit(Menu_Quit) = TRUE thenπ                        beginπ                           satisfied := true;π                           DeInitMouse;π                           ClrScr;π                           halt;π                        end;π                  until satisfied = true;π                  {ClrScr;}π               end;π         satisfied := false;π      end;π   DeInitMouse;                                        { Turn Mouse Off }π   ClrScr;πEND.ππ{ ------------------   UNIT FOR DEMO ABOVE -------------------- }ππunit frame2;πinterfaceπuses crt;ππCONSTπ   DtDs = 1;π   StSs = 2;π   DtSs = 3;π   StDs = 4;ππ   xSides : array[1..4, 1..6] of char = {xSides:array[1..4,1..6]of char =}π      (                                 {   (}π      (#201,#205,#187,#186,#200,#188),  {   ('╔','═','╗','║','╚','╝'),}π      (#218,#196,#191,#179,#192,#217),  {   ('┌','─','┐','│','└','┘'),}π      (#213,#205,#184,#179,#212,#190),  {   ('╒','═','╕','│','╘','╛'),}π      (#214,#196,#183,#186,#211,#189)   {   ('╓','─','╖','║','╙','╜')}π      );                                {   );}ππprocedure Frame(π   iSideType,π   iUpperLeftX,π   iUpperLeftY,π   iLowerRightX,π   iLowerRightY  : Integer);ππimplementationππprocedure Frame(π   iSideType,π   iUpperLeftX,π   iUpperLeftY,π   iLowerRightX,π   iLowerRightY   : Integer);ππvarπ   i: Integer;ππbeginπ   GotoXY(iUpperLeftX, iUpperLeftY);π   Write(xSides[iSideType][1]);π   for i:= iUpperLeftX+1 to iLowerRightX-1 doπ      beginπ         Write(xSides[iSideType][2]);π      end;π   Write(xSides[iSideType][3]);π   for i:= iUpperLeftY+1 to iLowerRightY-1 doπ     beginπ       GotoXY(iUpperLeftX , i);π       Write(xSides[iSideType][4]);π       GotoXY(iLowerRightX, i);π       Write(xSides[iSideType][4]);π     end;π   GotoXY(iUpperLeftX, iLowerRightY);π   Write(xSides[iSideType][5]);π   for i:= iUpperLeftX+1 to iLowerRightX-1 doπ      beginπ         Write(xSides[iSideType][2]);π      end;π   Write(xSides[iSideType][6]);πend;ππend.π                                                                                                             3      08-24-9413:57ALL                      JOHN HOWARD              Anivga Sprite Mouse V0.4 SWAG9408    +Y    40     l╚   (* ************************************************************************π   Example of ANIVGA sprite mouse using the default TurboVision Drivers unit.π   Procedures in Drivers unit divide MouseInt coordinates (i.e. SAR 3) by 8 toπ   convert into TPoint screen coordinates.  TPoint is an object containing aπ   pair of Integers.  Consequently, the default mouse is pixel precise for X =π   0..79 and Y = 0..24 but should be scaled back up for a larger range.ππ   Changing the source code from the Drivers unit is best approach.  Make aπ   clone unit that has the same keyboard/mouse constants and routines for theπ   event-loop.  And ignore the rest.  Otherwise multiply TEvent.Where valuesπ   by 8 repeatedly.  As shown, precision is reduced to 8 pixels as a result.π   ************************************************************************ *)π{$A+,B-,D+,L+,N-,E-,O-,R-,S-,V-,G-,F-,I-,X-}π{$M 16384,0,655360}πPROGRAM SpriteMouse;π{ Author: John Howard  jhπ  Version 0.4π  Date: July 23, 1994π}πUSES {original sinusoid code from Kai Rohrbacher}π     ANIVGAπ    ,Drivers;            {TurboVision event-driven mouse & keyboard}ππCONST LoadNumber=42;π      TileName='AEGYPTEN.COD';  {Path & name of any sprite tile to load}π      FirstTile=0;π      Tiles_per_Row=2;          {TileWidth}π      Tiles_per_Column=2;       {TileHeight}π      SpriteName='FLOWER.COD';  {Path & name of any sprite to load}π      CartoonName='HANTEL.LIB'; {Path & name of animated mouse cursor library}π      CartoonHandle=1;π      Cartoon=1;                {sprite number}π      MouseHandle=LoadNumber;   {Clone mouse cursor}π      Mouse=0;                  {sprite number}π      Surf=Mouse +15;           {just a sprite number above split index}π      OFF=0;                    {Switch sprite OFF}πVARπ    x : INTEGER;π    Event : TEvent;      {Drivers}π    MaxFrame : word;π    FrameCount : word;ππCONSTπ{ CRT Foreground and background color constants }π  Black         = 0;π  Blue          = 1;π  Green         = 2;π  Cyan          = 3;π  Red           = 4;π  Magenta       = 5;π  Brown         = 6;π  LightGray     = 7;ππ{ CRT Foreground color constants }π  DarkGray      = 8;π  LightBlue     = 9;π  LightGreen    = 10;π  LightCyan     = 11;π  LightRed      = 12;π  LightMagenta  = 13;π  Yellow        = 14;π  White         = 15;ππBEGINπ IF loadSprite(SpriteName,LoadNumber)=0π  THEN BEGINπ        WRITELN('Couldn''t access file '+SpriteName+' : '+GetErrorMessage);π        halt(1)π       END;π MaxFrame:=loadSprite(CartoonName,CartoonHandle);π{$IFDEF DEBUG}π    writeln(CartoonName+' contains : ', MaxFrame); halt(1);π{$ENDIF}π IF Error<>Err_Noneπ  THEN BEGINπ        WRITELN('Couldn''t access file '+CartoonName+' : '+GetErrorMessage);π        halt(1)π       END;π InitEvents;             {Drivers}π HideMouse;              {Drivers}ππ InitGraph;π IF loadTile(TileName, FirstTile)=0π  THEN BEGINπ        CloseRoutines;π        DoneEvents;      {Drivers}π        WRITELN('Couldn''t access file '+TileName+' : '+GetErrorMessage);π        halt(1)π       END;π FillBackground(LightRed);               {Border}π SetAnimateWindow(32,24, XMAX-32, YMAX-24);π SetBackgroundMode(SCROLLING);           {Tiles}π SetBackgroundScrollRange(0,0,XMAX,YMAX);  {Tiles}π MakeTileArea(FirstTile,Tiles_per_Row,Tiles_per_Column);ππ SetSplitIndex(Mouse + MaxFrame);π SetCycleTime(30);                       {millisec between frames}π SpriteN[Surf]:=LoadNumber;π SpriteN[Mouse]:=MouseHandle;            {clone sprite for default mouse}ππ FrameCount := 1;                        {min frame number}π repeatπ FOR x:=0 TO XMAX DO                     {vary the horizontal}π  BEGINπ   SpriteX[Surf]:=x;                     {sinusoid}π   SpriteY[Surf]:=TRUNC( sin(2.0*pi*x/XMAX)*(YMAX SHR 1)+YMAX SHR 1 );ππ   Event.What := evNothing;              {ClearEvent}π   GetMouseEvent(Event); {Drivers}π   if (Event.What and evMouse) <> 0 thenπ     if (Event.What = evMouseAuto) thenπ     begin   {animate mouse when button held down.  Note: sporadic reporting}π        SpriteN[Cartoon]:= OFF;π        SpriteN[Mouse]:= OFF;π        if (FrameCount < MaxFrame) then  {min..max frame or restart}π          inc(FrameCount)  {min frame number}π        elseπ          FrameCount := 1;               {start}π        SpriteN[Cartoon]:= FrameCount;π        SpriteX[FrameCount]:= Event.Where.X shl 3;π        SpriteY[FrameCount]:= Event.Where.Y shl 3;π     endπ     elseπ     begin   {default mouse cursor}π        SpriteN[Cartoon]:= OFF;π        SpriteN[Mouse]:= MouseHandle;π        SpriteX[Mouse]:= Event.Where.X shl 3;π        SpriteY[Mouse]:= Event.Where.Y shl 3;π     end; {if}π   {if "mouse (X,Y) within ClipRectangle" then}π   UpdateOuterArea := 2;                 {Required for non-dynamic background}π   Animate;π  END;ππ  GetKeyEvent(Event);    {Drivers}π until (Event.What = evKeyDown);         {keypressed}ππ CloseRoutines;π DoneEvents;             {Drivers}πEND.π                                                                                4      08-24-9417:53ALL                      OLAF BARTELT             Graphics Mouse Cursor    SWAG9408    σ┴±«    249    l╚   πUNIT  uMCursor;                               { (c) 1994 by NEBULA-Soft. }π      { Mausroutinen für Textmodus          } { Olaf Bartelt & Oliver Carow }π{ ═════════════════════════════ } INTERFACE { ═════════════════════════════ }πUSES  DOS, video;                             { Einbinden der Units         }ππ{ The unit VIDEO is also included in the SWAG distribution in the CRT.SWG   }ππ{ ─ Konstantendeklarationen ─────────────────────────────────────────────── }πCONST cLinke_taste                 = 1;       { linke Maustaste             }π      cRechte_taste                = 2;       { rechte Maustaste            }π      cMittlere_taste              = 4;       { mittlere Maustaste (bei 3)  }ππ      cursor_location_changed      = 1;π      left_button_pressed          = 2;π      left_button_released         = 4;π      right_button_pressed         = 8;π      right_button_released        = 16;π      middle_button_pressed        = 32;π      middle_button_released       = 64;ππ      lastmask                     : WORD    = 0;π      lasthandler                  : POINTER = NIL;ππ      click_repeat                 = 10;π      mousetextscale               = 8;π      vgatextgraphiccursor         : BOOLEAN = FALSE;πππ{ ─ Typendeklarationen ──────────────────────────────────────────────────── }πTYPE  mousetype                    = (twobutton, threebutton, another);π      buttonstate                  = (buttondown, buttonup);π      direction                    = (moveright, moveleft, moveup, movedown,πnomove);ππ{ ─ Variablendeklarationen ──────────────────────────────────────────────── }πVAR   mouse_present                : BOOLEAN;π      mouse_buttons                : mousetype;π      eventx, eventy, eventbuttons : WORD;π      eventhappened                : BOOLEAN;π      xmotions, ymotions           : WORD;π      mousecursorlevel             : INTEGER;π      fontpoints                   : BYTE;ππ      maxmousex             : INTEGER;π      maxmousey                    : INTEGER;πππ{ ─ exportierte Prozeduren und Funktionen ───────────────────────────────── }πPROCEDURE set_graphic_mouse_cursor;        { graphischen Mousecursor setzen }πPROCEDURE showmousecursor;ππ{ ══════════════════════════ } IMPLEMENTATION { ═══════════════════════════ }π{$IFDEF VER60}                                { in TP 6.0 gibt es SEGxxxx   }πCONST SEG0040 = $0040;                        { noch nicht! => definieren!  }π      SEGB800 = $B800;π      SEGA000 = $A000;π{$ENDIF}ππ{ ─ Typendeklarationen ──────────────────────────────────────────────────── }πTYPE  pTextgraphikcursor = ^tTextgraphikcursor;  { Zeiger auf Array         }π      tTextgraphikcursor = ARRAY[0..31] OF LONGINT;ππ      box                = RECORDπ                             left, top, right, bottom : WORD;π                           END;π      pChardefs          = ^tChardefs;π      tChardefs          = ARRAY[0..(32*8)] OF BYTE;ππ{ ─ Konstantendeklarationen ─────────────────────────────────────────────── }πCONST pfeil                  : tTextgraphikcursor =π{ Maske:  } ($3FFFFFFF, $1FFFFFFF, $0FFFFFFF, $07FFFFFF, $03FFFFFF, $01FFFFFF,π             $00FFFFFF, $007FFFFF, $003FFFFF, $007FFFFF, $01FFFFFF, $10FFFFFF,π             $B0FFFFFF, $F87FFFFF, $F87FFFFF, $FcFFFFFF,π{ Cursor: }  $00000000, $40000000, $60000000, $70000000, $78000000, $7C000000,π             $7E000000, $7F000000, $7F800000, $7F000000, $7C000000, $46000000,π             $06000000, $03000000, $03000000, $00000000);ππ      sanduhr : tTextgraphikcursor =        ($0001FFFF,  { 0000000000000001 }π                { Cursorform:      }         $0001FFFF,  { 0000000000000001 }π                                             $8003FFFF,  { 1000000000000011 }π                                             $C7C7FFFF,  { 1100011111000111 }π                                             $E38FFFFF,  { 1110001110001111 }π                                             $F11FFFFF,  { 1111000100011111 }π                                             $F83FFFFF,  { 1111100000111111 }π                                             $FC7FFFFF,  { 1111110001111111 }π                                             $F83FFFFF,  { 1111100000111111 }π                                             $F11FFFFF,  { 1111000100011111 }π                                             $E38FFFFF,  { 1110001110001111 }π                                             $C7C7FFFF,  { 1100011111000111 }π                                             $8003FFFF,  { 1000000000000011 }π                                             $0001FFFF,  { 0000000000000001 }π                                             $0001FFFF,  { 0000000000000001 }π                                             $0000FFFF,  { 0000000000000000 }π                                                { ^^^^ immer! (Textmodus)   }π                { Bildschirmmaske: }         $00000000,  { 0000000000000000 }π                                             $7FFC0000,  { 0111111111111100 }π                                             $20080000,  { 0010000000001000 }π                                             $10100000,  { 0001000000010000 }π                                             $08200000,  { 0000100000100000 }π                                             $04400000,  { 0000010001000000 }π                                             $02800000,  { 0000001010000000 }π                                             $01000000,  { 0000000100000000 }π                                             $02800000,  { 0000001010000000 }π                                             $04400000,  { 0000010001000000 }π                                             $08200000,  { 0000100000100000 }π                                             $10100000,  { 0001000000010000 }π                                             $20080000,  { 0010000000001000 }π                                             $7FFC0000,  { 0111111111111100 }π                                             $00000000,  { 0000000000000000 }π                                             $00000000); { 0000000000000000 }π                                                { ^^^^ immer! (Textmodus)   }ππ      vgatextgraphicptr      : pTextgraphikcursor = @pfeil;π                                                  { @sanduhr                }π{ ─ Variablendeklarationen ──────────────────────────────────────────────── }πVAR   hidebox                : box;π      regs                   : REGISTERS;π      vgastoredarray         : ARRAY[1..3, 1..3] OF BYTE;π      lasteventx, lasteventy : WORD;π      hasstoredarray         : BOOLEAN;π      oldexitproc            : POINTER;ππCONST chardefs               : pChardefs = NIL;π      charheight             = 16;π      defchar                = $D0;πππ{ ─ exportierte Prozeduren und Funktionen ───────────────────────────────── }πprocedure swap(var a,b : word);πvar c : word;πbeginπ c := a;π a := b;π b := c; {swap a and b}πend; {swap}ππprocedure setMouseCursor(x,y : word);πbeginπ with regs do beginπ  ax := 4;π  cx := x;π  dx := y; {prepare parameters}π  INTR($33, regs);π end; {with}πend; {setMouseCursor}ππFUNCTION x : WORD;πBEGINπ  regs.AX := 3;π  INTR($33, regs);π  x := regs.CX;πEND;ππFUNCTION y : WORD;πBEGINπ  regs.AX := 3;π  INTR($33, regs);π  y := regs.DX;πEND;ππprocedure mouseBox(left,top,right,bottom : word);πbeginπ if (left > right) then swap(left,right);π if (top > bottom) then swap(top,bottom); {make sure they are ordered}π regs.ax := 7;π regs.cx := left;π regs.dx := right;π INTR($33, regs); {set x range}π regs.ax := 8;π regs.cx := top;π regs.dx := bottom;π INTR($33, regs); {set y range}πend; {mouseBox}πππPROCEDURE initmouse;πVAR overridedriver : BOOLEAN;                 { wegen Hercules-Karten       }π    tempvideomode  : BYTE;                    { Zwischenspeicher für Modus  }πBEGINπ  overridedriver := FALSE;                    { erstmal nicht override!     }ππ  IF (FALSE AND (MEM[SEG0040:$0049] = 7)) THEN  { doch overriden?           }π  BEGINπ    MEM[SEG0040:$0049] := 6;                  { Ja: Videomodus vortäuschen  }π    overridedriver := TRUE;                   {     und override setzen!    }π  END;ππ  IF vgatextgraphiccursor = TRUE THEN         { Graphikcursor im Textmodus? }π  BEGINπ    tempvideomode := MEM[SEG0040:$0049];      { Videomodus zwischenspeichern}π    MEM[SEG0040:$0049] := 6;                  { anderen Modus vortäuschen   }π  END;ππ  WITH regs DO                                { Maustyp ermitteln           }π  BEGIN                                       { und Anzahl der Tasten auch  }π    AX := 0; BX := 0;                         { Maus initialisieren (00h)   }π    INTR($33, regs);                          { Mausinterrupt aufrufen      }ππ    mouse_present := (AX <> 0);               { überhaupt Maus vorhanden?   }π    IF (BX AND 2) <> 0 THEN mouse_buttons := twobutton  { Maustasten ermitt.}π                       ELSE IF (BX AND 3) > 0 THEN mouse_buttons := threebuttonπ                                              ELSE mouse_buttons := another;π  END;ππ  IF overridedriver = TRUE THEN MEM[SEG0040:$0049] := 7;  { override?       }π  IF vgatextgraphiccursor = TRUE THEN         { Graphikcursor im Textmodus? }π    MEM[SEG0040:$0049] := tempvideomode;      { Ja: Modus restaurieren!     }ππ  IF (NOT vgatextgraphiccursor) THEN fontpoints := mousetextscaleπ                                ELSE fontpoints := MEM[SEG0040:$0085];π  maxmousex := maxx * mousetextscale;         { Mausgrenzen ausrechnen      }π  maxmousey := maxy * fontpoints;ππ  mousebox(0, 0, (visiblex * mousetextscale)-1, (visibley * fontpoints)-1);π  eventbuttons := 0; eventhappened := FALSE;  { noch kein Event gewesen!    }ππ  xmotions := 8; ymotions := 16; mousecursorlevel := 0;  { Cursor nicht s.  }π  hasstoredarray := FALSE;                    { noch keine Daten im Array   }ππ  setmousecursor(visiblex * mousetextscale DIV 2, visibley * fontpoints DIV 2);π  eventx := x; eventy := y; lasteventx := eventx; lasteventy := eventy;πEND;ππPROCEDURE vgascreen2array(newposition, s2a, defaultrange : BOOLEAN);πVAR x, y : WORD;π    w, h : WORD;π    o, l : WORD;π    i, j : BYTE;πBEGINπ  IF (newposition = TRUE) THENπ  BEGINπ    x := eventx DIV mousetextscale;π    y := eventy DIV fontpoints;π  ENDπ  ELSEπ  BEGINπ    x := lasteventx DIV mousetextscale;π    y := lasteventy DIV fontpoints;π  END;ππ  w := visiblex - x; IF (w > 3) THEN w := 3;π  h := visibley - y; IF (h > 3) THEN h := 3;π  o := 2 * x + 2 * visiblex * y;π  l := 2 * visiblex - 2 * w;ππ  IF (defaultrange = TRUE) THENπ  BEGINπ    FOR i := 0 TO h - 1 DOπ    BEGINπ      FOR j := 0 TO w - 1 DOπ      BEGINπ        MEM[SEGB800:o] := defchar + i * 3 + j;π        INC(o, 2);π      END;π      INC(o, l);π    END;π  ENDπ  ELSEπ    IF (s2a = TRUE) THENπ    BEGINπ      FOR i := 1 TO h DOπ      BEGINπ        FOR j := 1 TO w DOπ        BEGINπ          vgastoredarray[i, j] := MEM[SEGB800:o];π          INC(o, 2)π        END;π        INC(o, l);π      END;π    ENDπ    ELSEπ    BEGINπ      FOR i := 1 TO h DOπ      BEGINπ        FOR j := 1 TO w DOπ        BEGINπ          MEM[SEGB800:o] := vgastoredarray[i, j];π          INC(o, 2);π        END;π        INC(o, l);π      END;π    END;πEND;ππPROCEDURE drawvgatextgraphiccursor;πTYPE  lp = ^LONGINT;πCONST sequencerport     = $3C4;π      sequenceraddrmode = $704;π      sequenceraddrnrml = $302;π      vgacontrolerport  = $3CE;π      cpureadmap2       = $204;π      cpuwritemap2      = $402;π      mapstartaddrA000  = $406;π      mapstartaddrB800  = $E06;π      oddevenaddr       = $304;πVAR   o, s              : WORD;π      i, j              : INTEGER;π      s1, s2, s3        : WORD;π      a                 : LONGINT;π      d, mc, ms         : lp;ππBEGINπ  ASMπ    PUSHFπ    CLIπ    MOV DX, sequencerportπ    MOV AX, sequenceraddrmodeπ    OUT DX, AXπ    MOV DX, vgacontrolerportπ    MOV AX, cpureadmap2π    OUT DX, AXπ    MOV AX, 5π    OUT DX, AXπ    MOV AX, mapstartaddrA000π    OUT DX, AXπ    POPFπ  END;ππ   o := 0;π   FOR i := 1 TO 3 DOπ   BEGINπ     s1 := vgastoredarray[i, 1] * 32;π     s2 := vgastoredarray[i, 2] * 32;π     s3 := vgastoredarray[i, 3] * 32;ππ     FOR j := 1 TO fontpoints DOπ     BEGINπ       INC(o); chardefs^[o] := MEM[SEGA000:s3];π       INC(o); chardefs^[o] := MEM[SEGA000:s2];π       INC(o); chardefs^[o] := MEM[SEGA000:s1];π       INC(o); INC(s1); INC(s2); INC(s3);π     END;π   END;ππ   s := eventx MOD mousetextscale;π   a := $FF000000 SHL (mousetextscale - s);ππ   d  := @chardefs^[(eventy MOD fontpoints) * SIZEOF(LONGINT)];π   ms := @vgatextgraphicptr^;π   mc := @vgatextgraphicptr^[charheight];ππ   FOR i := 1 TO charheight DOπ   BEGINπ     d^ := (d^ and ((ms^ shr s) or a)) or (mc^ shr s);π     INC(WORD(d), SIZEOF(LONGINT));π     INC(WORD(mc), SIZEOF(LONGINT));π     INC(WORD(ms), SIZEOF(LONGINT));π   END;ππ   ASMπ     MOV DX, sequencerportπ     MOV AX, cpuwritemap2π     OUT DX, AXπ   END;ππ   o := 0;π   for i := 0 to 2 do beginπ      s1 := (defChar + 3 * i    ) * 32;π      s2 := (defChar + 3 * i + 1) * 32;π      s3 := (defChar + 3 * i + 2) * 32;π      for j := 1 to fontPoints do beginπ         inc(o); { skip 4th byte }π         mem[segA000:s3] := charDefs^[o];π            { this code is changed to minimize DS variable space ! - RL }π         inc(o);π         mem[segA000:s2] := charDefs^[o];π         inc(o);π         mem[segA000:s1] := charDefs^[o];π         inc(o);π         inc(s1);π         inc(s2);π         inc(s3);π      end; { for j }π   end; { for i }ππ   (* now we will return the graphic adapter back to normal *)ππ   asmπ      pushf;π      cli; { disable intr .. }π      mov dx, sequencerPort;π      mov ax, sequencerAddrNrml;π      out dx, ax;π      mov ax, oddEvenAddr;π      out dx, ax;ππ      mov dx, vgaControlerPort;π      mov ax, 4; { map 0 for cpu reads }π      out dx, ax;π      mov ax, $1005;π      out dx, ax;π      mov ax, mapStartAddrB800;π      out dx, axπ      popf;π   end; { asm }ππ   vgaScreen2Array(true, false, true); { go ahead and paint it .. }ππend; {drawVGATextGraphicCursor}ππ(******************************************************************************π*                               showMouseCursor                               *π******************************************************************************)πprocedure showMouseCursor;ππbeginπ inc(mouseCursorLevel);π   if (not vgaTextGraphicCursor) then beginπ    regs.ax:=1; {enable cursor display}π    INTR($33, regs);π   end else if ((mouseCursorLevel = 1) and mouse_present) then beginπ      vgaScreen2Array(true, true, false);π      hasStoredArray := true;π      drawVGATextGraphicCursor;π   end;πend; {showMouseCursor}ππ(******************************************************************************π*                               hideMouseCursor                               *π******************************************************************************)πprocedure hideMouseCursor;ππbeginπ dec(mouseCursorLevel);π   if (not vgaTextGraphicCursor) then beginπ    regs.ax:=2; {disable cursor display}π    INTR($33, regs);π   end else if ((mouseCursorLevel = 0) and (hasStoredArray)) then beginπ      vgaScreen2Array(false, false, false);π      hasStoredArray := false;π   end;πend; {hideMouseCursor}πππ(******************************************************************************π*                                  getButton                                  *π******************************************************************************)πfunction getButton(Button : Byte) : buttonState;ππbeginπ        regs.ax := 3;π        INTR($33, regs);π        if ((regs.bx and Button) <> 0) thenπ                getButton := buttonDownπ                {bit 0 = left, 1 = right, 2 = middle}π        else getButton := buttonUp;πend; {getButton}ππ(******************************************************************************π*                                buttonPressed                                *π******************************************************************************)πfunction buttonPressed : boolean;ππbeginπ        regs.ax := 3;π        INTR($33, regs);π        if ((regs.bx and 7) <> 0) thenπ                buttonPressed := Trueπ        else buttonPressed := False;πend; {buttonPressed}πππ(******************************************************************************π*                                 lastXPress                                  *π******************************************************************************)πfunction lastXPress(Button : Byte) : word;ππbeginπ        regs.ax := 5;π        regs.bx := Button;π        INTR($33, regs);π        lastXPress := regs.cx;πend; {lastXpress}ππ(******************************************************************************π*                                 lastYPress                                  *π******************************************************************************)πfunction lastYPress(Button : Byte) : word;ππbeginπ        regs.ax := 5;π        regs.bx := Button;π        INTR($33, regs);π        lastYPress := regs.dx;πend; {lastYpress}ππ(******************************************************************************π*                                buttonPresses                                *π******************************************************************************)πfunction buttonPresses(Button : Byte) : word; {from last check}ππbeginπ        regs.ax := 5;π        regs.bx := Button;π        INTR($33, regs);π        buttonPresses := regs.bx;πend; {buttonPresses}ππ(******************************************************************************π*                                lastXRelease                                 *π******************************************************************************)πfunction lastXRelease(Button : Byte) : word;ππbeginπ        regs.ax := 6;π        regs.bx := Button;π        INTR($33, regs);π        lastXRelease := regs.cx;πend; {lastXRelease}ππ(******************************************************************************π*                                lastYRelease                                 *π******************************************************************************)πfunction lastYRelease(Button : Byte) : word;ππbeginπ        regs.ax := 6;π        regs.bx := Button;π        INTR($33, regs);π        lastYRelease := regs.dx;πend; {lastYRelease}ππ(******************************************************************************π*                               buttonReleases                                *π******************************************************************************)πfunction buttonReleases(Button : Byte) : word; {from last check}ππbeginπ        regs.ax := 6;π        regs.bx := Button;π        INTR($33, regs);π        buttonReleases := regs.bx;πend; {buttonReleases}ππ(******************************************************************************π*                             HardwareTextCursor                              *π******************************************************************************)πprocedure HardwareTextCursor(fromLine,toLine : byte);ππ{set text cursor to text, using the scan lines from..to,π        same as intr 10 cursor set in bios :π        color scan lines 0..7, monochrome 0..13 }ππbeginπ        regs.ax := 10;π        regs.bx := 1; {hardware text}π        regs.cx := fromLine;π        regs.dx := toLine;π        INTR($33, regs);πend; {hardwareTextCursor}ππ(******************************************************************************π*                             softwareTextCursor                              *π******************************************************************************)πprocedure softwareTextCursor(screenMask,cursorMask : word);ππ{ when in this mode the cursor will be achived by ANDing the screen wordπ        with the screen mask (Attr,Char in high,low order) andπ        XORing the cursor mask, ussually used by putting the screen attrπ        we want preserved in screen mask (and 0 into screen mask characterπ        byte), and character + attributes we want to set into cursor mask}ππbeginπ        regs.ax := 10;π        regs.bx := 0;        {software cursor}π        regs.cx := screenMask;π        regs.dx := cursorMask;π        INTR($33, regs);πend; {softwareMouseCursor}ππ(******************************************************************************π*                               recentXmovement                               *π******************************************************************************)πfunction recentXmovement : direction;ππ{from recent call to which direction did we move ?}ππvar d : integer;ππbeginπ        regs.ax := 11;π        INTR($33, regs);π        d := regs.cx;π        if (d > 0)π                then recentXmovement := moveRightπ        else if (d < 0)π                then recentXmovement := moveLeftπ        else recentXmovement := noMove;πend; {recentXmovement}ππ(******************************************************************************π*                               recentYmovement                               *π******************************************************************************)πfunction recentYmovement : direction;ππ{from recent call to which direction did we move ?}ππvarπ   d : integer;πbeginπ        regs.ax := 11;π        INTR($33, regs);π        d := regs.dx;π        if (d > 0)π                then recentYmovement := moveDownπ        else if (d < 0)π                then recentYmovement := moveUpπ        else recentYmovement := noMove;πend; {recentYmovement}πππ(******************************************************************************π*                               setEventHandler                               *π******************************************************************************)πprocedure setEventHandler(mask : word; handler        : pointer);ππ{handler must be a far interrupt routine }ππbeginπ        regs.ax := 12; {set event handler function in mouse driver}π        regs.cx := mask;π        regs.es := seg(handler^);π        regs.dx := ofs(handler^);π        INTR($33, regs);π        lastMask := mask;π        lastHandler := handler;πend; {set event Handler}ππ(******************************************************************************π*                               defaultHandler                                *π******************************************************************************)π{$F+} procedure defaultHandler; assembler; {$F-}πasmπ   push ds; { save TP mouse driver }π   mov ax, SEG @data;π   mov ds, ax; { ds = TP:ds, not the driver's ds }π   mov eventX, cx; { where in the x region did it occur }π   mov eventY, dx;π   mov eventButtons, bx;π   mov eventHappened, 1; { eventHapppened := true }π   pop ds; { restore driver's ds }π   ret;πend;ππ{   this is the default event handler , it simulates :ππ      beginπ               eventX := cx;π               eventY := dx;π               eventButtons := bx;π               eventhappened := True;π      end;ππ}ππ(******************************************************************************π*                                doPascalStuff                                *π* this is the pascal stuff that is called when vgaTextGraphicCursor mode has  *π* to update the screen.                                                       *π******************************************************************************)πprocedure doPascalStuff; far;πbeginπ   if (mouseCursorLevel > 0) then beginπ      if (hasStoredArray) then beginπ         VGAscreen2Array(false, false, false); { move old array to screen -πrestore }π         hasStoredArray := false;π      end;π      if (mouseCursorLevel > 0) then beginπ         VGAscreen2Array(true, true, false); { move new - from screen to arrayπ}π         hasStoredArray := true; { now we have a stored array }π         drawVGATextGraphicCursor; { do the low level stuff here }π         lastEventX := eventX;π         lastEventY := eventY; { this is the old location }π      end; { go ahead and draw it ... }π   end; { cursorLevel > 0 }πend; {doPascalStuff}ππ(******************************************************************************π*                            vgaTextGraphicHandler                            *π* this is the same as default handler, only we do the mouse location movement *π* ourself. Notice - if you use another handler, for mouse movement with       *π* VGA text graphic cursor - do the same !!!                                   *π******************************************************************************)πprocedure vgaTextGraphicHandler; far; assembler;πlabelπ   noCursorMove;πasmπ   push ds; { save TP mouse driver }π   push ax;π   mov ax, SEG @data;π   mov ds, ax; { ds = TP:ds, not the driver's ds }π   pop ax; { ax has the reason .. }π   mov eventX, cx; { where in the x region did it occur }π   mov eventY, dx;π   mov eventButtons, bx;π   mov eventHappened, 1; { eventHapppened := true }π   and ax, CURSOR_LOCATION_CHANGED; { o.k., do we need to handle mouse movement? }π   jz noCursorMove;π   call doPascalStuff;π   mov eventHappened, 0;π   { NOTICE - no movement events are detected in the out world ! - this is aπ     wintext consideration - It might be needed to track mouse movements,π     and then it should be changed ! - but this is MY default handler ! }πnoCursorMove: { no need for cursor movement handling }π   pop ds; { restore driver's ds }πend; {vgaTextGraphicHandler}ππ(******************************************************************************π*                                GetLastEvent                                 *π******************************************************************************)πfunction GetLastEvent(var x,y : word;π        var left_button,right_button,middle_button : buttonState) : boolean;ππbeginπ        getLastEvent := eventhappened; {indicate if any event happened}π        eventhappened := False; {clear to next read/event}π        x := eventX;π        y := eventY;π        if ((eventButtons and cLinke_taste) <> 0) thenπ                left_button := buttonDownπ        else left_button := buttonUp;π        if ((eventButtons and cRechte_taste) <> 0) thenπ                right_button := buttonDownπ        else right_button := buttonUp;π        if ((eventButtons and cMittlere_taste) <> 0) thenπ                middle_button := buttonDownπ        else middle_button := buttonUp;πend; {getLastEvent}ππ(******************************************************************************π*                              setDefaultHandler                              *π******************************************************************************)πprocedure setDefaultHandler(mask : WORD);ππ{get only event mask, and set event handler to defaultHandler}ππbeginπ   if (vgaTextGraphicCursor) then beginπ      mask := mask or CURSOR_LOCATION_CHANGED; { we MUST detect cursor movementπ}π           setEventHandler(mask,@vgaTextGraphicHandler);π   end elseπ           setEventHandler(mask,@defaultHandler);πend; {setDefaultHandler}ππ(******************************************************************************π*                              defineSensetivity                              *π******************************************************************************)πprocedure defineSensetivity(x,y : word);ππbeginπ        regs.ax := 15;π        regs.cx := x; {# of mouse motions to horizontal 8 pixels}π        regs.dx := y; {# of mouse motions to vertical 8 pixels}π        INTR($33, regs);π        XMotions := x;π        YMotions := y; {update global unit variables}πend; {defineSensetivity}ππ(******************************************************************************π*                              setHideCursorBox                               *π******************************************************************************)πprocedure setHideCursorBox(left,top,right,bottom : word);ππbeginπ        regs.ax := 16;π        regs.es := seg(HideBox);π        regs.dx := ofs(HideBox);π        HideBox.left := left;π        HideBox.right := right;π        HideBox.top := top;π        HideBox.bottom := bottom;π        INTR($33, regs);πend; {setHideCursorBox}ππ(******************************************************************************π*                               waitForRelease                                *π* Wait until button is release, or timeOut 1/100 seconds pass. (might miss a  *π* tenth (1/10) of a second.                                                                                                                     *π******************************************************************************)πprocedure waitForRelease(timeout : WORD);πvarπ    sHour, sMinute, sSecond, sSec100 : word;        { Time at start }π    cHour, cMinute, cSecond, cSec100 : word;        { Current time        }π    stopSec                             : longInt;π    currentSec                          : longInt;π    Delta                             : longInt;πbeginπ    getTime(sHour, sMinute, sSecond, sSec100);π    stopSec := (sHour*36000 + sMinute*600 + sSecond*10 + sSec100 + timeOut) modπ                    (24*360000);π    repeatπ           getTime(cHour, cMinute, cSecond, cSec100);π           currentSec := (cHour*36000 + cMinute*600 + cSecond*10 + cSec100);π           Delta := currentSec - stopSec;π    until (not ButtonPressed) or (Delta >=0) and (Delta < 36000);πend; {waitForRelease}ππ(******************************************************************************π*                              swapEventHandler                               *π* handler is a far routine.                                                   *π******************************************************************************)πprocedure swapEventHandler(mask : WORD; handler : POINTER);πbeginπ   regs.ax := $14;π   regs.cx := mask;π        regs.es := seg(handler^);π        regs.dx := ofs(handler^);π        INTR($33, regs);π   lastMask := regs.cx;π   lastHandler := ptr(regs.es,regs.dx);πend; {swapEventHandler}ππ(******************************************************************************π*                            getMouseSaveStateSize                            *π******************************************************************************)πfunction getMouseSaveStateSize : WORD;πbeginπ   regs.ax := $15;π   INTR($33, regs);π   getMouseSaveStateSize := regs.bx;πend; {getMouseSaveStateSize}ππ(******************************************************************************π*                           setVgaTextGraphicCursor                           *π******************************************************************************)πprocedure setVgaTextGraphicCursor;πbeginπ   vgaTextGraphicCursor := false; { assume we can not .. }π   if (queryAdapterType <> vgaColor) thenπ      exit;π   vgaTextGraphicCursor := true;πend; {setVgaTextGraphicCursor}ππ(******************************************************************************π*                          resetVgaTextGraphicCursor                          *π******************************************************************************)πPROCEDURE resetvgatextgraphiccursor;πBEGINπ  vgatextgraphiccursor := FALSE;πEND;ππPROCEDURE myexitproc; FAR;πBEGINπ  EXITPROC := oldexitproc;π  IF (vgatextgraphiccursor AND hasstoredarray) THENπ    vgascreen2array(FALSE, FALSE, FALSE);π  DISPOSE(chardefs);π  resetvgatextgraphiccursor;π  initmouse;πEND;ππPROCEDURE set_graphic_mouse_cursor;         { graphischen Mauscursor setzen }πBEGINπ  setvgatextgraphiccursor; initmouse; setdefaulthandler(left_button_pressed);πEND;ππ{ ─ Hauptprogramm der Unit ──────────────────────────────────────────────── }πBEGINπ   eventx := 0; eventy := 0; eventhappened := FALSE;π   NEW(chardefs); initmouse;π   oldexitproc := EXITPROC;π   EXITPROC    := @myexitproc;πEND.ππ